package com.northpool.operator.statistics.dataset;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.annotation.OutputParam;
import com.northpool.operator.annotation.OutputParams;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.custom.DatasetParam;
import com.northpool.operator.type.TypeEnum;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.modules.geoprocess.operator.IPipelineOperator;
import com.northpool.stpclient.operator.bean.DatasetBean;
import com.northpool.stpclient.operator.bean.OperatorBean;
import com.northpool.stpclient.operator.bean.ParamBean;
import com.northpool.stpclient.operator.bean.PipelineBean;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

@OperatorInfo(
        ref = "TotalAreaStatisticsOperator",
        name = "面积和统计",
        description = "统计分析-面积和统计"
)
@OutputParams({
        @OutputParam(ref = "totalResult", name = "面积统计和结果", type = TypeEnum.STRING)
})
public class TotalAreaStatisticsOperator extends StpClientOperatorBase {
    String dataSourceId;
    String tableName;
    String spatialField;
    String sqlFilter;
    String areaField;

    @InputParams({
            @InputParam(ref = "dataset", name = "数据集", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true),
            @InputParam(ref = "spatialField", name = "空间字段", desc = "空间字段名称，如: geom", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "sqlFilter", name = "SQL过滤条件", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "areaField", name = "面积字段", desc = "面积字段名称，如：_area__", type = TypeEnum.STRING, required = true),
    })
    public TotalAreaStatisticsOperator() {
        super();
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        DatasetParam dataset = params.getDataset("dataset");
        this.dataSourceId = dataset.getDataSourceId();
        this.tableName = dataset.getTableName();
        this.spatialField = params.getStr("spatialField");
        this.sqlFilter = params.getStr("sqlFilter");
        this.areaField = params.getStr("areaField");

        PipelineBean pipeline = new PipelineBean();
        pipeline.setResultFile(System.getProperty("user.dir") + File.separator + "result_file");
        DatasetBean dataSet = new DatasetBean();
        dataSet.setDataSourceId(dataSourceId);
        dataSet.setTableName(tableName);
        dataSet.setSqlFilter(sqlFilter);
        pipeline.setDataSet(dataSet);

        List<OperatorBean> ops = new LinkedList<>();
        ops.add(buildAreaCal());
        ops.add(buildPgSink());

        pipeline.setOperators(ops);
        IPipelineOperator iPipelineOperator = this.client.pipelineOperator();
        BaseResponse response = iPipelineOperator.startPipeline(pipeline);
        iPipelineOperator.onStart(response.getRequestId(), () -> {
            this.log("面积统计开始");
        });
        iPipelineOperator.onSuccess(response.getRequestId(), () -> {
            this.log("面积统计成功");
            String log = iPipelineOperator.log(response.getRequestId());
            this.log(log);
            this.successExit();
        });
        iPipelineOperator.onError(response.getRequestId(), () -> {
            this.error("面积统计失败：{}", iPipelineOperator.log(response.getRequestId()));
            this.failedExit();
        });
        this.waiting(24);
    }

    public OperatorBean buildAreaCal() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.spatial.vector.AreaCalOperator");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("spatialField", spatialField));
        params.add(new ParamBean("areaField", areaField));
        operatorBean.setStartParam(params);

        return operatorBean;
    }

    public OperatorBean buildPgSink() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.basic.statistics.AddOperator");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("fieldName", this.areaField));
        params.add(new ParamBean("totalResult", "out", "String", "totalResult"));
        operatorBean.setStartParam(params);

        return operatorBean;
    }

}
